/*
 * GraphPartitioningStrategy.java
 *
 * This file is part of FUJIWARA.
 * Copyright (C) 2010 Loris Fichera    (loris.fichera@gmail.com)
 *                    Daniele Marletta (danielemar86@gmail.com)
 *
 * FUJIWARA is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * FUJIWARA is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with FUJIWARA.  If not, see <http://www.gnu.org/licenses/>.
 */

package graphclient;
import java.util.List;
import java.util.LinkedList;

/**
 *
 * @author Loris Fichera
 * @author Daniele Marletta
 *
 */
public abstract class GraphPartitioningStrategy {

    protected static java.util.List<java.lang.Integer> countNeighbours(java.util.List<java.lang.Integer> arg0) {
        graphservice.GraphServiceService service = new graphservice.GraphServiceService();
        graphservice.GraphService port = service.getGraphServicePort();
        return port.countNeighbours(arg0);
    }

    protected static java.util.List<java.lang.String> processConnections(java.util.List<java.lang.Integer> arg0) {
        graphservice.GraphServiceService service = new graphservice.GraphServiceService();
        graphservice.GraphService port = service.getGraphServicePort();
        return port.processConnections(arg0);
    }
    
    protected static java.util.List<java.lang.Integer> computeHops(java.util.List<java.lang.Integer> arg0, java.util.List<java.lang.Integer> arg1, int arg2) {
        graphservice.GraphServiceService service = new graphservice.GraphServiceService();
        graphservice.GraphService port = service.getGraphServicePort();
        return port.computeHops(arg0, arg1, arg2);
    }

    public abstract int [] countNeighbours (int [][] adjMatrix);
    public abstract String [] processConnections (int [] neighbourCount);
    public abstract int [] computeHops ( int [] adjVector,
                                         int [] neighbourCount,
                                         int hyperNodeIndex);
}


class DistributedGraphPartitioning extends GraphPartitioningStrategy {

    public int [] countNeighbours (int [][] adjMatrix) {

        int [] adjVector = GraphUtils.squareMatrixToVector (adjMatrix);

        List<Integer> l = new LinkedList<Integer>();

        for (int i = 0; i < adjVector.length; i ++) {
            l.add(adjVector[i]);
        }

        // invoke web method
        // a try-catch needed here
        List<Integer> count = countNeighbours (l);
        int [] neighbourCount = new int [count.size()];

        for (int i = 0; i < count.size(); i++) {
            neighbourCount [i] = count.get (i);
        }

        return neighbourCount;
    }

    public String [] processConnections (int [] neighboursCount) {

        List<Integer> l = new LinkedList<Integer>();

        for (int i = 0; i < neighboursCount.length; i++) {
            l.add(neighboursCount[i]);
        }

        //invoke web method
        // a try catch is needed here
        List<String> classes = processConnections(l);
        
        return classes.toArray(new String[0]);
    }

    public int [] computeHops ( int [] adjVector,
                                int [] neighboursCount,
                                int hypernode) {

        List<Integer> adjList = new LinkedList<Integer>();
        List<Integer> neighboursCountList = new LinkedList<Integer>();

        for (int i : adjVector)
            adjList.add (i);

        for (int count : neighboursCount)
            neighboursCountList.add (count);

        // actually invoke web method
        List<Integer> hopsList = computeHops (adjList,
                                              neighboursCountList,
                                              hypernode);

        int [] hops = new int[hopsList.size()];

        for (int i = 0; i < hopsList.size(); i ++)
            hops[i] = hopsList.get(i);

        return hops;
    }
}
